package com.example.demo.config;
import org.springframework.integration.mqtt.event.*;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.event.MqttConnectionFailedEvent;
import org.springframework.integration.mqtt.event.MqttIntegrationEvent;
import org.springframework.integration.mqtt.event.MqttSubscribedEvent;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.context.event.EventListener;
import org.springframework.integration.mqtt.event.*;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Configuration
@IntegrationComponentScan // 扫描 @MessagingGateway 等注解
public class MqttConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(MqttConfig.class);
    @Value("${mqtt.broker.url}")
    private String brokerUrl;
    // 客户端配置
    @Value("${mqtt.client.publisher-id}")
    private String publisherClientId;
    @Value("${mqtt.client.subscriber-id}")
    private String subscriberClientId;
    @Value("${mqtt.default.topic}")
    private String defaultTopic;
    @Value("${mqtt.qos}")
    private int defaultQos;
    @Value("${mqtt.broker.username}")
    private String username;
    @Value("${mqtt.broker.password}")
    private String password;

    // --- 通用 MQTT Client Factory ---
    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        MqttConnectOptions options = new MqttConnectOptions();
        options.setServerURIs(new String[]{brokerUrl});
        options.setUserName(username);
        options.setPassword(password.toCharArray());
        options.setCleanSession(true); // 设置为 false 以启用持久会话和离线消息
        options.setAutomaticReconnect(true); // 启用自动重连
        options.setConnectionTimeout(10); // 连接超时时间 (秒)
        options.setKeepAliveInterval(20); // 心跳间隔 (秒)
        factory.setConnectionOptions(options);

        LOGGER.info("MQTT已连接");
        return factory;
    }


    // --- MQTT 消息发布 (Outbound) ---
    @Bean
    public MessageChannel mqttOutboundChannel() {
        return new DirectChannel(); // 或者 PublishSubscribeChannel
    }

    @Bean
    @ServiceActivator(inputChannel = "mqttOutboundChannel")
    public MessageHandler mqttOutbound(MqttPahoClientFactory clientFactory) {
        MqttPahoMessageHandler messageHandler =
                new MqttPahoMessageHandler(publisherClientId, clientFactory); // 使用独立的 Client ID
        messageHandler.setAsync(true); // 推荐异步发送
        messageHandler.setDefaultTopic(defaultTopic); // 默认主题，可以被消息头覆盖
        messageHandler.setDefaultQos(defaultQos); // 默认QoS，可以被消息头覆盖
        // messageHandler.setDefaultRetained(false); // 默认是否保留消息
        return messageHandler;
    }

    // 定义一个网关接口，用于发送消息到 mqttOutboundChannel
    // Spring Integration 会自动实现这个接口
    @MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
    public interface MqttGateway {
        void sendToMqtt(String payload);
        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload);
        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
        // 可以定义更多重载方法，例如发送 byte[]
        // void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, byte[] payload);
    }


    // --- MQTT 消息订阅 (Inbound) ---
    @Bean
    public MessageChannel mqttInputChannel() {
        return new DirectChannel();
    }

    @Bean
    public MqttPahoMessageDrivenChannelAdapter mqttAdapter(
            MqttPahoClientFactory clientFactory,
            MessageChannel mqttInputChannel) {

        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter(
                        "dynamicSubscriber",
                        clientFactory);
        adapter.setCompletionTimeout(2000);
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setOutputChannel(mqttInputChannel);
        adapter.setAutoStartup(false);
        return adapter;
    }
    @Bean
    public MqttSubscriptionManager subscriptionManager(
            MqttPahoMessageDrivenChannelAdapter adapter) {
        return new MqttSubscriptionManager(adapter);
    }
//    @Autowired
//    private MqttSubscriptionManager subscriptionManager;
//    @Bean
//    public void initSubscriptions() {
//        // 订阅单个主题
//        subscriptionManager.subscribe("test/topic1", 1);
//    }

    // 消息处理器，处理从 mqttInputChannel 接收到的消息
    @ServiceActivator(inputChannel = "mqttInputChannel")
    public void handleIncomingMqttMessage(org.springframework.messaging.Message<String> message) {
        String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC, String.class);
        String payload = message.getPayload();
        Integer qos = message.getHeaders().get(MqttHeaders.RECEIVED_QOS, Integer.class);
        Boolean retained = message.getHeaders().get(MqttHeaders.RETAINED, Boolean.class);
//        LOGGER.info("Received MQTT Message - Topic: [{}], QoS: [{}], Retained: [{}], Payload: [{}]",
//                topic, qos, retained, payload);

        // 在这里处理你的业务逻辑
    }



    // 可选: 监听 MQTT 事件 (连接成功，连接丢失等)

    @EventListener
    public void handleMqttEvents(MqttIntegrationEvent event) {
        LOGGER.info("MQTT Event: {}", event);
        if (event instanceof MqttConnectionFailedEvent) {
            MqttConnectionFailedEvent failedEvent = (MqttConnectionFailedEvent) event;
            LOGGER.error("MQTT连接失败", failedEvent.getCause());
        } else if (event instanceof MqttSubscribedEvent) {
            MqttSubscribedEvent subscribedEvent = (MqttSubscribedEvent) event;
            LOGGER.info("MQTT连接成功，客户端ID: {}", subscribedEvent.getMessage());
        }
        //还有 MqttMessageSentEvent, MqttMessageDeliveredEvent 等
    }


}
